package com.eastfair.certificate.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.annotation.annotation.tenant.TenantAuth;
import com.eastfair.auth.dto.UserAccountDto;
import com.eastfair.auth.vo.UserAccountVo;
import com.eastfair.boot.request.PageParams;
import com.eastfair.certificate.dao.BusinessMapper;
import com.eastfair.certificate.dto.*;
import com.eastfair.certificate.entity.Blacklist;
import com.eastfair.certificate.entity.CarRecord;
import com.eastfair.certificate.entity.CertificateIndex;
import com.eastfair.certificate.entity.CertificateUser;
import com.eastfair.certificate.enumeration.*;
import com.eastfair.certificate.service.*;
import com.eastfair.certificate.vo.CertificateUserVO;
import com.eastfair.certificate.vo.CertificateVO;
import com.eastfair.common.req.CertificateIndexReq;
import com.eastfair.common.vo.CarInOffRecord;
import com.eastfair.common.vo.CertBlackList;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.core.utils.DateUtils;
import com.eastfair.echo.core.EchoService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 前端控制器
 *
 * </p>
 *
 * @author clm
 * @date 2022-08-02
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/sycn")
@Api(value = "SycnController", tags = "")
public class SycnController {

    @Autowired
    private EchoService echoService;

    @Autowired
    private CarRecordService carRecordService;

    @Autowired
    private CertificateUserService certificateUserService;

    @Autowired
    private CertificateIndexService certificateIndexService;

    @Value("${com.eastfair.projectId}")
    private Long projectId;

    @Autowired
    private BlacklistService blacklistService;

    /**
     * @return
     * @Author ligang
     * @Description 同步车辆出入信息
     * @Date 11:17 2023/1/20
     * @Param [carInOffRecord]
     **/
    @PostMapping("/sycnCarOff")
    public R sycnCarOff(@RequestBody CarInOffRecord carInOffRecord) {
        ContextUtil.setProjectId(projectId);
        CarRecord carRecord = new CarRecord();
        BeanUtils.copyProperties(carInOffRecord, carRecord);
        if ("0".equals(carInOffRecord.getInOrOut())) {
            //0:进场，1：出场
            carRecord.setInOrOut(CarRecordInOrOutEnum.IN);
        } else if ("1".equals(carInOffRecord.getInOrOut())) {
            //0:进场，1：出场
            carRecord.setInOrOut(CarRecordInOrOutEnum.OUT);
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(DateUtils.DEFAULT_DATE_TIME_FORMAT);
        carRecord.setInTime(LocalDateTime.parse(carInOffRecord.getInTime(), df));
        carRecord.setPassTime(LocalDateTime.parse(carInOffRecord.getPassTime(), df));
        carRecordService.save(carRecord);
        return R.success();
    }

    /**
     * @return
     * @Author ligang
     * @Description 同步证件信息
     * @Date 11:17 2023/1/20
     * @Param [carInOffRecord]
     **/
    @GetMapping("/sycnCertificate")
    @TenantAuth(enabled = true)
    public R<List<CertificateUserDTO>> sycnCertificate() {
        ContextUtil.setProjectId(projectId);
        List<CertificateUserDTO> result = new ArrayList<>();
        PageParams<CertificateUserDTO> params = new PageParams<>();
        CertificateUserDTO certificateUserDTO = new CertificateUserDTO();
        certificateUserDTO.setIsSycn(BusinessConstant.NO);
        certificateUserDTO.setFirstAuthStatus(CertificateUserFirstAuthStatusEnum.CHECK_SUCC);
        certificateUserDTO.setSecondAuthStatus(CertificateUserSecondAuthStatusEnum.CHECK_SUCC);
        certificateUserDTO.setIsPay(BusinessConstant.YES);
        certificateUserDTO.setCertificateTypes(Arrays.asList(
                CertificateUserCertificateTypeEnum.CAR,
                CertificateUserCertificateTypeEnum.POWER,
                CertificateUserCertificateTypeEnum.OTHER));
        certificateUserDTO.setIsCarNumberNotNull(1);
        certificateUserDTO.setAppointmentInEndTimeOfGe(LocalDateTime.now());
        params.setModel(certificateUserDTO);
        params.setSize(20);
        params.setCurrent(1);
        IPage<CertificateUser> page = params.buildPage();
        QueryWrapper<CertificateUser> queryWrapper = certificateUserService.assembleQueryWrapper(certificateUserDTO);
        IPage<CertificateUser> certificateUserIPage = certificateUserService.page(page, queryWrapper);

        List<CertificateUserVO> certificateUserVOList = certificateUserService.doToVos(certificateUserIPage.getRecords());
        //组装公司展会业务数据
        certificateUserService.assembleBusinssData(certificateUserVOList);
        log.info("certificateUserIPage is {}", JSONObject.toJSONString(certificateUserVOList));
        if (CollectionUtil.isNotEmpty(certificateUserVOList)) {
            for (CertificateUserVO model : certificateUserVOList) {
                CertificateUserDTO certificateUserDTO1 = new CertificateUserDTO();
                BeanUtils.copyProperties(model, certificateUserDTO1);
                certificateUserDTO1.setId(model.getId());
                certificateUserDTO1.setCompanyName(model.getServiceProviderVO() != null ? model.getServiceProviderVO().getCompanyName() : "");
                certificateUserDTO1.setExhibitorName(model.getServiceProviderVO() != null ? model.getServiceProviderVO().getCompanyName() : "");
//                certificateUserDTO1.setBooth("无");
                log.info("certificateUserDTO1 is {}", JSONObject.toJSONString(certificateUserDTO1));
                if (verifyCertificateUser(certificateUserDTO1)) {
                    result.add(certificateUserDTO1);
                }
            }

            //更新已同步状态
            if (CollectionUtil.isNotEmpty(certificateUserIPage.getRecords())) {
                for (CertificateUser model : certificateUserIPage.getRecords()) {
                    model.setIsSycn(BusinessConstant.YES);
                    certificateUserService.updateById(model);
                }
            }
        }
        log.info("sycnCertificate result is {}", JSONObject.toJSONString(result));
        return R.success(result);
    }

    public Boolean verifyCertificateUser(CertificateUserDTO certificateUserDTO) {
        log.info("certificateUserDTO is {}", JSONObject.toJSONString(certificateUserDTO));
        if (certificateUserDTO.getId() == null
                || certificateUserDTO.getCertificateId() == null
                || certificateUserDTO.getExhibitionId() == null
                || StringUtils.isBlank(certificateUserDTO.getCompanyName())
                || StringUtils.isBlank(certificateUserDTO.getCardNumber())
                || StringUtils.isBlank(certificateUserDTO.getFullName())
                || StringUtils.isBlank(certificateUserDTO.getContactInformation())
                || certificateUserDTO.getExhibitionId() == null
                || StringUtils.isBlank(certificateUserDTO.getExhibitorName())
                || StringUtils.isBlank(certificateUserDTO.getCarNumber())
                || StringUtils.isBlank(certificateUserDTO.getSpaceCode())
//                || certificateUserDTO.getIsDraw() == null
                || certificateUserDTO.getAppointmentInStartTime() == null
//                || certificateUserDTO.getIsSpecial() == null
                || StringUtils.isBlank(certificateUserDTO.getAxleCount())) {
            return false;
        }

        return true;
    }

    /**
     * @return
     * @Author ligang
     * @Description 同步证件指标信息
     * @Date 11:17 2023/1/20
     * @Param [carInOffRecord]
     **/
    @PostMapping("/sycnCertificateIndex")
    @TenantAuth(enabled = true)
    public R<List<CertificateIndexReq>> sycnCertificateIndex(@RequestBody CertificateIndexDTO certificateIndexDTO) {
        ContextUtil.setProjectId(projectId);
        certificateIndexDTO.setEndTimeOfGe(LocalDateTime.now());
//        certificateIndexDTO.setStartTimeOfLe(LocalDateTime.now());
        List<CertificateIndexReq> result = new ArrayList<>();
        PageParams<CertificateIndex> params = new PageParams<>();
        params.setSize(30);
        params.setCurrent(1);
        IPage<CertificateIndex> page = params.buildPage();
        QueryWrapper<CertificateIndex> queryWrapper = certificateIndexService.assembleQueryWrapper(certificateIndexDTO);
        IPage<CertificateIndex> certificateIndexIPage = certificateIndexService.page(page, queryWrapper);
        if (CollectionUtil.isNotEmpty(certificateIndexIPage.getRecords())) {
            for (CertificateIndex model : certificateIndexIPage.getRecords()) {
                CertificateIndexReq certificateIndexReq = new CertificateIndexReq();
                BeanUtils.copyProperties(model, certificateIndexReq);
                certificateIndexReq.setId(model.getId());
                certificateIndexReq.setClassify(model.getClassify().getCode());
                result.add(certificateIndexReq);
            }
        }
        return R.success(result);
    }


    /**
     * @return
     * @Author ligang
     * @Description 同步黑名单信息
     * @Date 11:17 2023/1/20
     * @Param [carInOffRecord]
     **/
    @PostMapping("/blackList")
    @TenantAuth(enabled = true)
    public R sycnBlackList(@RequestBody List<CertBlackList> certBlackLists) {
        ContextUtil.setProjectId(projectId);
        List<Blacklist> delBlacklistList = new ArrayList<>();
        List<Blacklist> updBlacklistList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(certBlackLists)) {
            for (CertBlackList certBlackList : certBlackLists) {
                Blacklist blacklist = new Blacklist();
                blacklist.setUserName(certBlackList.getUserName());
                blacklist.setCardNumber(certBlackList.getCardNumber());
                blacklist.setPhoneNumber(certBlackList.getPhoneNumber());
                blacklist.setCompanyName(certBlackList.getCompanyName());
                blacklist.setDataResource(certBlackList.getSource());
                blacklist.setKind(BlacklistKindEnum.VENUE);
                if (0 == certBlackList.getAction()) {
                    //0 新增  1修改   2删除
                    blacklistService.addBlack(blacklist);
                } else if (1 == certBlackList.getAction()) {
                    //0 新增  1修改   2删除
                    BlacklistDTO blacklistDTO = new BlacklistDTO();
                    blacklistDTO.setUserName(certBlackList.getUserName());
                    blacklistDTO.setCardNumber(certBlackList.getCardNumber());
                    blacklistDTO.setPhoneNumber(certBlackList.getPhoneNumber());
                    blacklistDTO.setCompanyName(certBlackList.getCompanyName());
                    List<Blacklist> blacklistList = blacklistService.list(blacklistDTO, null);
                    if (CollectionUtil.isNotEmpty(blacklistList)) {
                        updBlacklistList.addAll(blacklistList);
                    }
                } else if (2 == certBlackList.getAction()) {
                    //0 新增  1修改   2删除
                    BlacklistDTO blacklistDTO = new BlacklistDTO();
                    blacklistDTO.setUserName(certBlackList.getUserName());
                    blacklistDTO.setCardNumber(certBlackList.getCardNumber());
                    blacklistDTO.setPhoneNumber(certBlackList.getPhoneNumber());
                    blacklistDTO.setCompanyName(certBlackList.getCompanyName());
                    List<Blacklist> blacklistList = blacklistService.list(blacklistDTO, null);
                    if (CollectionUtil.isNotEmpty(blacklistList)) {
                        delBlacklistList.addAll(blacklistList);
                    }
                }
            }
        }

        if (CollectionUtil.isNotEmpty(delBlacklistList)) {
            del(delBlacklistList);
        }
        if (CollectionUtil.isNotEmpty(updBlacklistList)) {
            upd(updBlacklistList);
        }
        return R.success();
    }

    public void del(List<Blacklist> delBlacklistList) {
        List<Long> blackIds = delBlacklistList.stream().map(Blacklist::getId).collect(Collectors.toList());
        //删除
        blacklistService.removeBlack(blackIds);
    }

    public void upd(List<Blacklist> updBlacklistList) {
        List<Long> blackIds = updBlacklistList.stream().map(Blacklist::getId).collect(Collectors.toList());
        //删除
        blacklistService.removeBlack(blackIds);
        for (Blacklist blacklist : updBlacklistList) {
            //重新添加
            blacklistService.addBlack(blacklist);
        }
    }


}
